package cn.bonoon.kernel.menus;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.bonoon.kernel.menus.privileges.ChannelPrivilegeInspector;
import cn.bonoon.kernel.menus.tips.MenuTipHandler;
import cn.bonoon.kernel.support.IOperator;
import cn.bonoon.kernel.util.StringHelper;
import cn.bonoon.util.PathUtil;

/**
 * 一个子系统的定义；包含生成系统框架的所有界面信息
 * @author jackson
 *
 */
final class ModuleDefinitionImpl extends AstractModule{

	/** 子系统的频道 */
	private final List<ChannelDefinitionImpl> channels;
	
	/** 需要在子系统下显示的提示信息 */
	private List<MenuTipHandler> tipHandlers;

	/** 该功能下面的所有菜单的集合 */
	private final Map<String, AbstractMenuable> itemCached;
	
	public ModuleDefinitionImpl(List<ChannelDefinitionImpl> channels) {
		this.channels = channels;
		this.itemCached = new HashMap<String, AbstractMenuable>(32);
	}
	
	//这里的originalId没有被加密过
	ModuleDefinitionImpl init(PlatformContext platformContext, ParentContainer parent) {
		final String parentPath = parent.getPath();
		
		this.internalId = id;
		this.id = platformContext.idGenerate(internalId);
		this.xpath = platformContext.xpathGenerate(parent.getXpath());
		this.path = PathUtil.path(parentPath, path);
		this.endpoint = PathUtil.path(parentPath, id + "!sys.do");
		this.name = StringHelper.get(name, parent.getName());
		
		platformContext.add(this, describe);
		
		final ModuleContext moduleContext = new ModuleContext(){

			@Override
			public ModuleDefinition getModule() {
				return ModuleDefinitionImpl.this;
			}

			@Override
			public void add(String id, AbstractMenuable menuable) {
				itemCached.put(id, menuable);
			}

			@Override
			public void add(MenuTipHandler handler) {
				if(null == tipHandlers) tipHandlers = new ArrayList<>();
				tipHandlers.add(handler);
			}
		};
		
		if(null == style) style = new StyleDefinitionImpl();
		style.init(platformContext, this);
		
//		if(null == des) des = platformContext.getDes();
		
//		int internalOrder = 0;
		for (ChannelDefinitionImpl channel : channels) {
//			channel.parent = this;
//			channel.xpath = String.valueOf(internalOrder++);
			channel.init(platformContext, moduleContext, /*itemCached, */this);
		}
		
		// 排序
		Collections.sort(channels);
		return this;
	}
	
	public AbstractMenuable getItem(String id) {
		return itemCached.get(id);
	}
	
	@Override
	public final List<ChannelDefinition> getChannels(IOperator user, ChannelPrivilegeInspector privilege) {
		//进行预处理
		List<ChannelDefinition> cis = new ArrayList<>();
		for (ChannelDefinition channel : channels) {
			if (privilege.hasPrivilege(channel)) {
				/*
				 *  有权限访问这个频道，但不一定有权限访问该频道所指向的子菜单
				 *  如果频道不是直接使用url，而是指定子菜单，并没有该子菜单的访问权限
				 *  则需要重新从有权限的子菜单下取出第一个有权限的子菜单
				 */
				cis.add(channel);
			}
		}
		return cis;
	}
	
	public final List<ChannelDefinition> getChannels() {
		return new ArrayList<ChannelDefinition>(channels);
	}

//
//	public final String getEndpoint() {
//		return endpoint;
//	}
//
//	public final void setEndpoint(String endpoint) {
//		this.endpoint = endpoint;
//	}

}
